package com.atjava.webspider.util;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;

import org.apache.commons.lang.StringUtils;

import com.atjava.webspider.logic.ConfigLogic;
import com.atjava.webspider.model.AppConfig;

public class HttpUtil {
	
	public static void disconnect(HttpURLConnection con){
		if(con != null)
			con.disconnect();
	}
	
	/**
	 * 根据URL获取一个HTTP连接
     *@param  url  Description of Parameter
     *@return      The validConnection value
     */
    public static HttpURLConnection getValidConnection(URL url) {
        HttpURLConnection httpurlconnection = null;
        try {
            URLConnection urlconnection;
            AppConfig config = ConfigLogic.getAppConfig();
            com.atjava.webspider.model.Proxy cfgProxy = config.getProxy();
            if(cfgProxy != null && cfgProxy.getUse()){
            	InetSocketAddress address = new InetSocketAddress 
            	(cfgProxy.getServer(),cfgProxy.getPort());
            	Proxy proxy = new Proxy
            	(Proxy.Type.valueOf(cfgProxy.getType()), address);
            	urlconnection = url.openConnection(proxy);
            }else{
            	urlconnection = url.openConnection();
            }
            
            urlconnection.setConnectTimeout(6 * 1000);
            //设置模拟浏览器 不被服务端拒绝
            urlconnection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)");
            urlconnection.setRequestProperty("Content-type", "text/html");
            urlconnection.setRequestProperty("contentType","gb2312");
            urlconnection.setUseCaches(false);
            urlconnection.connect();

            if (!(urlconnection instanceof HttpURLConnection)) {
                LogUtil.info("Not an http connection: " + url);
                disconnect(httpurlconnection);
                return null;
            }
            httpurlconnection = (HttpURLConnection) urlconnection;
            // httpurlconnection.setFollowRedirects(true);
            int responsecode = httpurlconnection.getResponseCode();
            switch (responsecode) {
                // here valid codes!
                case HttpURLConnection.HTTP_OK:
                case HttpURLConnection.HTTP_MOVED_PERM:
                case HttpURLConnection.HTTP_MOVED_TEMP:
                    break;
                default:
                    LogUtil.info("Invalid response code: " + responsecode + " " + url);
                	disconnect(httpurlconnection);
                	return null;
            }
        } catch (Exception ex) {
            LogUtil.info("打开失败: " + url);
            disconnect(httpurlconnection);
            return null;
        }
        return httpurlconnection;
    }


    /**
     * 获取安全Http连结，默认重试次数为3次
     *
     *@param  connection  a connection
     *@return             an InputStream
     */
    public static InputStream getSafeInputStream(HttpURLConnection connection,int times) {
    	if(times == 0){
    		times = 3;
    	}
        InputStream inputstream = null;
        for (int i = 0; i < times; ) {
            try {
                inputstream = connection.getInputStream();
                break;
            } catch (IOException ioexception1) {
                LogUtil.info("Error at opening stream: " + ioexception1);
                i++;
            }
        }
        return inputstream;
    }
    
    /**
     * 根据一个连接获取网页文本信息
     *
     *@param  connection  Description of Parameter
     *@return             The content value
     */
    public static String getTextResource(HttpURLConnection connection,String charset) {
        InputStream inputstream = getSafeInputStream(connection,0);
        if (inputstream == null) {
            return null;
        }
        try {
        	 int bufferSize = ConfigLogic.getAppConfig().getBufferSize();
             FileSystemUtil fsu = new FileSystemUtil(bufferSize);
        	return fsu.readText(inputstream,charset);
        } catch (Exception exception) {
            LogUtil.log(exception);
        } finally {
            FileSystemUtil.close(inputstream);
        }
        return null;
    }

    /**
     * Streams to disk
     *
     *@param  inputstream  input stream
     *@param  outputfile   file to write to
     *@return              Description of the Returned Value
     
    public static long writeDataResource1(HttpURLConnection connection,File outputfile) {
    	InputStream is = getSafeInputStream(connection,0);
    	
        long writtenBytesCount = 0;
        FileOutputStream os = null;
        try {
        	int bufferSize = ConfigLogic.getAppConfig().getBufferSize();
            FileSystemUtil fsu = new FileSystemUtil(bufferSize);
            if (is == null) {
            	LogUtil.log("Inputstream is null: " + outputfile);
                return writtenBytesCount;
            }
            // create local directory
            outputfile.getParentFile().mkdirs();
            os = new FileOutputStream(outputfile);
            fsu.readWriteData(is, os);
        } catch (Exception exp) {
            LogUtil.log(exp);
        } finally{
        	FileSystemUtil.close(is);
        	FileSystemUtil.close(os);
        }
        return writtenBytesCount;
    }*/
    
    public static boolean isAvailableLink(String link){
    	if (link.startsWith("#"))
			return false;
		if (link.length() >= 11 && link.substring(0, 11).equalsIgnoreCase("javascript:"))
			return false;
		return true;
    }
    
    public static String getAbsoluteUrl(String baseUrl,String linkUrl){
		String link = linkUrl;	
		try {
			//绝对路径
			if(!linkUrl.startsWith("http://")){
				//相对项目路径
				if(linkUrl.startsWith("/")){
					link = getHost(baseUrl) + linkUrl;
				//相对路径
				}else{
					if(baseUrl.endsWith("/"))
						baseUrl = baseUrl.substring(0, baseUrl.length()-1);
					int n = StringUtils.countMatches(linkUrl,"../");
					if( n == 0 ){
						int idx = baseUrl.lastIndexOf("/");
						return baseUrl.substring(0, idx) + "/" + link;
					}else{
						String[] fd = baseUrl.split("/");
						int k = fd.length-3-1;
						if(k >= n){
							String folder = "";
							for(int i=0;i<k-n;i++){
								folder += "/" + fd[3+i];
							}
							link = getHost(baseUrl) + folder + "/" + linkUrl.substring(linkUrl.lastIndexOf("../")+3);
						}else{
							return null;
						}
					}
				}
				return "http://" + link;
			}else{
				return link;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
    
    public static void main(String[] args)throws Exception {
		
    	String url = "http://localhost:8080/a/index.html";
    	String linkUrl = "images/test.gif";
    	System.out.println(getAbsoluteUrl(url, linkUrl));
    	
    	/*String str1 = "http://atjava.com?asd.asp";
    	String str2 = "http://images.atjava.com/kyo";
    	String str4 = "http://www.atjava.com?kyo.do";
    	String str3 = "http://svn.atjava.com:8080/sdf.asp";
    	
    	System.out.println(getDomain(str1));
    	System.out.println(getDomain(str2));
    	System.out.println(getDomain(str3));
    	System.out.println(getDomain(str4));*/
	}
    
	public static String getHost(String url){
		if(!url.startsWith("http://")){
			return "";
		}
		String[] s = url.replace("?", "/").split("/");
		if(s[2].indexOf(":") > 0)
			return s[2].substring(0, s[2].indexOf(":"));
		return s[2];
	}
	
	public static String getDomain(String url){
		String host = getHost(url);
		String [] s = host.split("\\.");
		if(s.length == 2)
			return host;
		if(s.length == 3)
			return s[1] + "." + s[2];
		return "";
	}
	
	public static String getWebResourceName(String url){
		if(url.endsWith("/"))
			url = url.substring(0,url.length()-1);
		return url.substring(url.lastIndexOf("/")+1);
	}
    

    /**
     *  Description of the Method
     *
     *@param  url       Description of Parameter
     *@param  basepath  Description of Parameter
     *@return           Description of the Returned Value
     
    public static File URLToLocalFile(File basepath, URL url) {

        String strPort;
        int port = url.getPort();
        if (port != -1) {
            strPort = ";" + port;
        } else {
            strPort = "";
        }

        String localpathname = url.getHost() + strPort + url.getPath();

        // il path assoluto locale (nella dir di output)
        File localfile = new File(basepath, localpathname);
        // LogUtil.log("localfile: " + localfile);

        return localfile;
    }*/

    /*public static URL transformURL(String url) {

        URL transformed_url = null;
		try {
			transformed_url = new URL(url);
		} catch (MalformedURLException e) {
			LogUtil.log("transformURL: " + url);
		}
        return transformed_url;
    }*/

}
